
package com.be.beadmin.project.impl;


import cn.hutool.core.util.ObjectUtil;
import com.be.beadmin.basicData.dto.output.UserEx;
import com.be.beadmin.basicData.service.UserService;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.logging.annotation.Log;
import com.be.beadmin.project.Util.MinioUtil;
import com.be.beadmin.project.entity.PayFileInfo;
import com.be.beadmin.project.entity.PayFileInfo_;
import com.be.beadmin.project.entity.PayInfo;
import com.be.beadmin.service.service.SerialNumberService;
import lombok.RequiredArgsConstructor;
import com.be.beadmin.project.mapper.PayFileInfoMapperEx;
import com.be.beadmin.project.repository.PayFileInfoRepository;
import com.be.beadmin.project.service.PayFileInfoService;
import com.be.beadmin.project.dto.input.PayFileInfoDto;
import com.be.beadmin.project.dto.output.PayFileInfoEx;
import com.be.beadmin.project.dto.input.PayFileInfoQueryCriteria;
import com.be.beadmin.project.mapper.PayFileInfoMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Order;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* @description 服务实现
* @author zjm
* @date 2023-08-31
**/
@Service
@RequiredArgsConstructor
public class PayFileInfoServiceImpl implements PayFileInfoService {

    @Autowired
    private  PayFileInfoRepository payFileInfoRepository;
    @Autowired
    private  PayFileInfoMapper payFileInfoMapper;
    @Autowired
    private  PayFileInfoMapperEx payFileInfoExMapper;
    @Autowired
    private MinioUtil minioUtil;
    @Autowired
    private UserService userService;
    private static final Logger log = LoggerFactory.getLogger(PayFileInfoServiceImpl.class);
    @Autowired
    private SerialNumberService serialNumberService;
    @Override
    public Page<PayFileInfoEx> getPayFileInfoByPage(PageEntity pageEntity) {
            Pageable pageable = PageRequest.of(
            pageEntity.getCurrent() -1,
            pageEntity.getPageSize());
            Page<PayFileInfo> page = payFileInfoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 =   JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(PayFileInfo_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if(pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(PayFileInfo_.createTime).as(Date.class)));
                    }
                    return  criteriaBuilder.and(list.toArray(p));
                    }
                    , pageable);
            Page<PayFileInfoEx> page1 = page.map(payFileInfoExMapper::toEntity);
            return page1;

    }

    @Override
    public void addPayFileInfo(PayFileInfoDto payFileInfoDto) {
            PayFileInfo result = payFileInfoRepository.findPayFileInfoByIdAndDelete(payFileInfoDto.getId(), 0);
            if(ObjectUtil.isNotEmpty(result)) {
                throw new BeadminException("PayFileInfo不存在,请重新查询");
            }
            PayFileInfo payFileInfo = payFileInfoMapper.toEntity(payFileInfoDto);
            payFileInfoRepository.save(payFileInfo);
    }

    @Override
    public void updatePayFileInfo(PayFileInfoDto payFileInfoDto) {
            PayFileInfo payFileInfo = payFileInfoRepository.findPayFileInfoById(payFileInfoDto.getId());
            payFileInfo = payFileInfoMapper.toEntity(payFileInfoDto);
            payFileInfoRepository.save(payFileInfo);
    }


    @Override
    public void delPayFileInfo(String id) {
        PayFileInfo payFileInfo = payFileInfoRepository.findPayFileInfoById(id);
        payFileInfo.setDelete(1);
        payFileInfoRepository.save(payFileInfo);
    }

    @Override
    public void delPayFileInfos (List<String> ids) { }


    /**
     * 付款信息附件上传
     *
     * @param infoId
     * @param stageName
     * @param multipartFile
     * @param bucketName
     */
    @Override
    @Log("付款信息附件上传")
    public void uploadFileByPayInfo(HttpServletRequest request, String infoId, String stageName, MultipartFile[] multipartFile, String bucketName) {

        UserEx user = userService.viewBaseInfo(request);
        /**
         * stageName有4个选项
         *
         *
         * advance 预付款
         * stageFirst 阶段款1
         * stageSecond 阶段款2
         * final 尾款
         */

        PayFileInfo payFileInfo = null;
        checkStageName(stageName);

//        switch (stageName) {
//            case "advance":
//                break;
//            case "stageFirst":
//                break;
//            case "stageSecond":
//                break;
//            case "final":
//                break;
//            default:
//                throw new BeadminException("请输入正确的阶段名称:[         * advance 预付款\n" +
//                        "         * stageFirst 阶段款1\n" +
//                        "         * stageSecond 阶段款2\n" +
//                        "         * final 尾款]");
//        }
        payFileInfo = payFileInfoRepository.findPayFileInfoByInfoIdAndPayInfoStageNameAndDelete(infoId,stageName, 0);
        if (payFileInfo == null) {
            payFileInfo = new PayFileInfo();
        }
        payFileInfo.setUploaderId(user.getId());
        payFileInfo.setUploaderName(user.getName());
        payFileInfo.setUploadTime(new Date());
        payFileInfo.setInfoId(infoId);
        payFileInfo.setPayInfoStageName(stageName);

        //附件相关
        for(MultipartFile file:multipartFile) {
            if (file != null) {
                payFileInfo.setPayFileCode(serialNumberService.getNextSnByCode("PayFileCode"));
                payFileInfo.setPayFileName(file.getOriginalFilename());
                payFileInfo.setBucketName(bucketName);

                String uploadFileName = payFileInfo.getPayFileCode() + "+" + stageName + "+" + payFileInfo.getPayFileName();

                String preview_url = null;
                try {
                    preview_url = minioUtil.uploadFile2(file, uploadFileName, bucketName);
                } catch (Exception e) {
                    log.info("异常信息", e.getMessage());
                    throw new BeadminException("文件上传失败");
                }
                payFileInfo.setFileUrl(preview_url);
            }
            PayFileInfo fileInfo = payFileInfoRepository.findPayFileInfoByInfoIdAndPayInfoStageNameAndDelete(infoId, stageName, 0);
            if (fileInfo != null) {
                payFileInfo.setId(fileInfo.getId());
            }
            payFileInfoRepository.save(payFileInfo);
        }



    }

    private void checkStageName(String stageName) {
        if (!stageName.equals("advance") && !stageName.equals("stageFirst")&&!stageName.equals("stageSecond")&&!stageName.equals("final")) {
            throw new BeadminException("请输入正确的阶段名称:[         * advance 预付款\n" +
                    "         * stageFirst 阶段款1\n" +
                    "         * stageSecond 阶段款2\n" +
                    "         * final 尾款]");
        }

    }

    /**
     * 获取付款信息附件
     *
     * @param request
     * @param infoId
     * @param stageName
     * @param bucketName
     */
    @Override
    public PayFileInfoEx getFileByPayInfo(HttpServletRequest request, String infoId, String stageName, String bucketName) {
        checkStageName(stageName);
        PayFileInfo payFileInfo = payFileInfoRepository.findPayFileInfoByInfoIdAndPayInfoStageNameAndDelete(infoId, stageName, 0);
        if (payFileInfo == null) {
            return null;
        } else {
            return payFileInfoExMapper.toEntity(payFileInfo);
        }
    }

    /**
     * @param payFileInfoId
     * @return
     */
    @Override
    public String getPayPreviewUrl(String payFileInfoId) throws Exception {
        PayFileInfo payFileInfo = payFileInfoRepository.findPayFileInfoByIdAndDelete(payFileInfoId, 0);

        String fileCode = payFileInfo.getPayFileCode();
        String fileName = payFileInfo.getPayFileName();
        String stageName = payFileInfo.getPayInfoStageName();
        String FileName = fileCode+"+"+stageName+"+"+fileName ;
        String preview_url = minioUtil.getPreviewFileUrl(payFileInfo.getBucketName(),FileName);
        payFileInfo.setFileUrl(preview_url);
        payFileInfoRepository.save(payFileInfo);
        return preview_url;
    }
}